渲染引擎分析 - 鸿蒙(OpenHarmony) JS UI 源码阅读笔记
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo sync -c
OpenHarmony/
├── applications # 应用程序样例
├── base # 基础软件服务子系统集
├── docs
├── domains # 增强软件服务子系统集
├── drivers # 驱动子系统
├── foundation # 系统基础能力子系统集
│ ├── aafwk # Ability 框架
│ ├── ace # JS UI 框架
│ │ ├── ace_engine # ACE 1.0, 仓库名: ace_ace_engine
│ │ └── ace_engine_lite # ACE 2.0, 仓库名: ace_engine_lite
│ ├── appexecfwk # 用户程序框架和包管理模块
│ └── graphic # 图形库相关的子系统
├── interface
│ └── sdk-js # JS API 的 TS 类型文件
├── kernel # LiteOS 内核
│ ├── liteos_a
│ └── liteos_m
├── test
└── third_party
Frontend: 前端代码的执行环境,JS 或者 JSON,有这层抽象或许还可以支持其他脚本引擎。
TaskExecutor: 单一线程内的任务管理器,类似其他渲染引擎中的 TaskRunner。
AssetManager: 资源管理器,可用于加载 JS 代码、图片、字体等资源。应该也具备缓存能力。
PipelineContext: 渲染管线的管理类,监听 vsync 回调刷新内部脏节点的布局、绘制、渲染。
AceView: 渲染生成的 UI 根节点,可以贴到外层容器中。
PlatformResRegister: 平台资源的注册和管理,以及部分通信接口,可在这里实现同层渲染功能。
Frontend
部分,有三种不同类型的实现,分别是基于渲染指令的命令式 UI、声明式 UI、以及无需脚本引擎,用 JSON 文件渲染的 UI。命令式 UI 和 声明式 UI 都是用 QuickJS 作为脚本引擎,声明式 UI 里包含了 V8 的抽象,但是这部分好像没有开源出来。1JS Frontend (命令式 UI)
xx.hml
的模板文件、xx.css
的样式文件、xx.js
的脚本文件以及 xx.json
配置文件。<div class="container">
<text class="title-text">{{headTitle}}</text>
</div>
/* xxx.css */
.container {
flex-direction: column;
margin-top: 20px;
margin-left: 30px;
}
.title-text {
color: #1a1a1a;
font-size: 50px;
}
// xxx.js
export default {
data: {
headTitle: 'Capture the Beauty in This Moment'
}
}
ace
的模块中,可以用 import 导入,环境中也有 ace
这个全局环境:import * as ace from 'ace'
// 创建 body 节点
ace.domCreateBody(0, 'div', {/* attrs */}, {/* styles */}, {/* events */})
2Declarative Frontend (声明式 UI)
@Component
class MyDemo {
Column(
Text('Hello World!'),
Text('Some text here')
.fontsize(36)
.color(Color.Red)
).center()
}
3Card Frontend (无脚本 UI)
template
、styles
、actions
、data
这几部分,模板里可以写花括号的数据绑定 {{some.data}}
,里边可以写简单的 JS 表达式,也不是完全静态的。而且 CardFrontend 类上有 UpdateData()
接口,可以更新模板的数据,具备一定的动态化能力。OnVsyncEvent()
回调,如果 surface 已经初始化好,则依次刷新内部的脏节点,如果包含动画,则调用 RequestFrame()
请求触发下一帧 vsync。首先 dirty Elements 会触发 Rebuild()
重新构建 RenderNode,并且调用 MarkNeedLayout()
把它加到待布局的队列里,然后 FlushLayout
会刷新这个队列,调用节点的 OnLayout()
方法计算布局,然后把自身再加入到待绘制的队列里,然后 FlushRender()
依次调用节点的 Repaint()
方法重新绘制,生成 layer tree。* 参考链接
OpenHarmony 官网:https://www.openharmony.cn/
ACE Lite: https://gitee.com/openharmony/ace_engine_lite
ACE Engine: https://gitee.com/openharmony/ace_ace_engine
配置文件:https://gitee.com/openharmony/manifest/blob/master/default.xml
ACE 架构图:https://gitee.com/openharmony/ace_engine_lite/blob/OpenHarmony-2.0-Canary/figures/JS%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E6%A1%86%E6%9E%B6.png
类小程序 DSL:https://device.harmonyos.com/en/docs/apiref/js-framework-file-0000000000616658
新 ACE 架构图:https://gitee.com/openharmony/ace_ace_engine/blob/OpenHarmony-2.0-Canary/figures/JS-UI%E6%A1%86%E6%9E%B6%E6%9E%B6%E6%9E%84.png
qjs_engine.cpp: https://gitee.com/openharmony/ace_ace_engine/blob/OpenHarmony-2.0-Canary/frameworks/bridge/js_frontend/engine/quickjs/qjs_engine.cpp#L1925-1940
TaskCenter.ts: https://gitee.com/openharmony/third_party_jsframework/blob/OpenHarmony-2.0-Canary/runtime/main/manage/event/TaskCenter.ts#L127-133
FlutterSceneBuilder: https://gitee.com/openharmony/ace_ace_engine/blob/OpenHarmony-2.0-Canary/frameworks/core/pipeline/layers/flutter_scene_builder.h